package com.per.mybootall.service.impl;

import com.per.mybootall.common.Const;
import com.per.mybootall.dao.LogisticsMapper;
import com.per.mybootall.dao.OrderMapper;
import com.per.mybootall.dao.RoleAndUserMapper;
import com.per.mybootall.dao.UserMapper;
import com.per.mybootall.pojo.Logistics;
import com.per.mybootall.pojo.User;
import com.per.mybootall.service.LoginInter;
import com.per.mybootall.shiro.UserRealm;
import com.per.mybootall.utils.GetPhoto;
import com.per.mybootall.utils.RandomValidateCodeUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class Loginimpl implements LoginInter {
   @Autowired
   private  UserMapper userMapper;
    @Autowired
    private User user;
    @Autowired
    private RoleAndUserMapper roleAndUserMapper;
    @Autowired
    private UserRealm userRealm;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private GetPhoto getPhoto;
    @Autowired
    private RandomValidateCodeUtil randomValidateCodeUtil;
    @Autowired
    private LogisticsMapper logisticsMapper;
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public Map<String, Object> login(String username, String password, String photomessahes, String uuid){
        Map<String,Object> map=new HashMap<String, Object>();

        String redisInUuid= (String) redisTemplate.opsForValue().get(uuid);
        if (redisInUuid==null||!redisInUuid.equals(photomessahes)){
            map.put("msg","验证码错误");
            return map;
        }


        //1.获取subject
        Subject subject = SecurityUtils.getSubject();
        //2.封装用户数据
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
        //3.执行登陆方法
        try{
            subject.login(usernamePasswordToken);
          //把用户id一起返回前端，在向redis添加购物车的时候带过来为key
            int userid=userMapper.selectIdByname(username,password);
            System.out.println("登陆人的id:=======>>>>>"+userid);
//            int rootid=

            if(userid==0){
                //就不是user和root
                map.put("msg","该用户不存在");
                return  map;
            }

            //角色查询：

           int res= userMapper.selectRoleById(username);
            System.out.println(res);
            if(res==Const.Role.ROLE_ADMIN){
                //管理员页面
                map.put("role","root");
                //rootTokenUuid是管理员请求的验权token
                String rootTokenUuid=randomValidateCodeUtil.getUuid();
                //判断是哪一个管理员的标志
                String rootUuid=randomValidateCodeUtil.getUuid();
                map.put("rootToken",rootTokenUuid);
                map.put("whoAreRoot",rootUuid);
                map.put("thisUserId",userid);
                redisTemplate.opsForValue().set(rootUuid,rootTokenUuid);

                return map;
            }

            map.put("role","user");
            //userTokenUuid是普通用户请求的验权token
            String userTokenUuid=randomValidateCodeUtil.getUuid();
            //判断是哪一个user的标志
            String userUuid=randomValidateCodeUtil.getUuid();
            map.put("userToken",userTokenUuid);
            map.put("whoAreUser",userUuid);
            map.put("thisUserId",userid);




            //判断是否有该用户的相关物流，便于物流消息推送
                  int userids=   userMapper.selectIdByname(username,password);
                  List<Logistics> list=logisticsMapper.selectIdByNameParamesInt(userids);
            if(list.size()>0){
                //该物流存在
                System.out.println("该物流存在");
                map.put("logistics",Const.logistics.LOGISTICS_EXIST);
            }



            redisTemplate.opsForValue().set(userUuid,userTokenUuid);

            redisTemplate.delete(uuid);
            System.out.println(uuid+"验证码已验证使用并删除");
            return map;
            //没有任何异常就是登陆成功,有任何异常都是登陆失败
        }catch (UnknownAccountException e){

            map.put("msg","用户名不存在");
            return map;
            //UnknownAccountException异常是用户名不存在
        }catch (IncorrectCredentialsException e){

            map.put("msg","密码错误");
            return map;
            //UnknownAccountException异常是密码错误
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public  Map<String,String> register(String username,String password,String photouuid,int yanzma){
    Map<String,String> map=new HashMap<String, String>();
      int photonumberRedis= (int) redisTemplate.opsForValue().get(photouuid);
      if(photonumberRedis<=999||photonumberRedis!=yanzma){
          map.put("msg","手机验证码错误");
          return map;
      }else {
          user.setUsername(username);
          user.setPassword(password);
          int insert = userMapper.insert(user);
          int insertRole=roleAndUserMapper.insertRole(username, Const.Role.ROLE_CUSTOMER);
          if(insert>0&&insertRole>0){
              map.put("msg","注册成功");
              redisTemplate.delete(photouuid);
              return map;
          }
        }
        map.put("msg","注册失败");
        return map;
            }

    @Override
    public String nameisexist(String name){
//    int exist=userMapper.selectIdByname(name);
//    if(exist>0){
//        return "用户已经存在";
//    }
        return "用户不存在";
        }

        @Override
        public Map<String,String> getPhoto(String photo) throws JSONException {
           //验证码：code
            Map<String,String> map=new HashMap<String ,String>();
            int  code= getPhoto.note(photo);
            String photouuid=randomValidateCodeUtil.getUuid();
            //电话号码验证码5分钟有效
            redisTemplate.opsForValue().set(photouuid,code,5, TimeUnit.MINUTES);
            map.put("photouuid",photouuid);
            return map;
        }
}
